Distribution of explicit and implicit partisan identities by country.
$Austria
der_pid Vote reported Don't know Other NA
Party ID reported 3774 192 6 6
No Party ID 2622 900 78 0
Other 48 6 24 0
NA 0 0 0 6
Total 6444 1098 108 12
$Belgium
der_pid Vote reported Don't know Other NA
Party ID reported 5040 210 36 6
No Party ID 1434 888 132 0
Other 24 12 42 0
NA 0 0 0 6
Total 6498 1110 210 12
$Bulgaria
der_pid Vote reported Don't know Other NA
Party ID reported 2520 168 102 0
No Party ID 1548 918 450 0
Other 114 18 48 0
NA 0 0 0 6
Total 4182 1104 600 6
$Croatia
der_pid Vote reported Don't know Other NA
Party ID reported 3102 348 336 0
No Party ID 1320 1554 420 0
Other 126 12 216 0
NA 0 0 0 6
Total 4548 1914 972 6
$`Czech Republic`
der_pid Vote reported Don't know Other NA
Party ID reported 4236 546 60 6
No Party ID 828 966 72 0
Other 18 6 60 0
NA 0 0 0 12
Total 5082 1518 192 18
$Denmark
der_pid Vote reported Don't know Other NA
Party ID reported 5568 360 72 6
No Party ID 540 444 48 0
Other 66 54 36 0
NA 0 0 0 6
Total 6174 858 156 12
$Estonia
der_pid Vote reported Don't know Other NA
Party ID reported 3120 72 126 0
No Party ID 1728 324 204 0
Other 60 0 18 0
NA 0 0 0 12
Total 4908 396 348 12
$Finland
der_pid Vote reported Don't know Other NA
Party ID reported 4068 204 72 18
No Party ID 1284 972 156 6
Other 60 12 102 0
NA 0 0 0 6
Total 5412 1188 330 30
$France
der_pid Vote reported Don't know Other NA
Party ID reported 4176 180 54 36
No Party ID 1110 1194 150 0
Other 6 12 0 0
NA 0 0 0 18
Total 5292 1386 204 54
$Germany
der_pid Vote reported Don't know Other NA
Party ID reported 3666 90 132 174
No Party ID 1764 948 222 66
Other 6 6 54 0
NA 0 0 0 0
Total 5436 1044 408 240
$Greece
der_pid Vote reported Don't know Other NA
Party ID reported 3894 222 72 6
No Party ID 1194 912 198 0
Other 222 48 192 0
NA 0 0 0 6
Total 5310 1182 462 12
$Hungary
der_pid Vote reported Don't know Other NA
Party ID reported 3642 168 24 0
No Party ID 1134 708 144 0
Other 48 6 42 0
NA 0 0 0 0
Total 4824 882 210 0
$Ireland
der_pid Vote reported Don't know Other NA
Party ID reported 2916 120 48 0
No Party ID 2016 1032 144 0
Other 48 0 36 0
NA 0 0 0 6
Total 4980 1152 228 6
$Italy
der_pid Vote reported Don't know Other NA
Party ID reported 4950 366 30 0
No Party ID 618 900 84 0
Other 24 6 36 0
NA 0 0 0 18
Total 5592 1272 150 18
$Latvia
der_pid Vote reported Don't know Other NA
Party ID reported 2346 174 156 0
No Party ID 2652 1062 378 0
Other 66 12 36 0
NA 0 0 0 6
Total 5064 1248 570 6
$Lithuania
der_pid Vote reported Don't know Other NA
Party ID reported 3132 192 24 0
No Party ID 2724 1122 192 0
Other 138 18 48 0
NA 0 0 0 0
Total 5994 1332 264 0
$Netherlands
der_pid Vote reported Don't know Other NA
Party ID reported 4704 270 54 0
No Party ID 1182 948 96 0
Other 18 6 36 0
NA 0 0 0 12
Total 5904 1224 186 12
$Poland
der_pid Vote reported Don't know Other NA
Party ID reported 4950 240 0 0
No Party ID 1242 690 24 0
Other 30 0 6 0
NA 0 0 0 6
Total 6222 930 30 6
$Portugal
der_pid Vote reported Don't know Other NA
Party ID reported 3672 498 216 0
No Party ID 1068 1218 288 0
Other 24 18 102 0
NA 6 4 0 0
Total 4770 1738 606 0
$Romania
der_pid Vote reported Don't know Other NA
Party ID reported 4614 186 126 6
No Party ID 2316 1128 300 0
Other 54 36 78 0
NA 8 0 0 10
Total 6992 1350 504 16
$Slovakia
der_pid Vote reported Don't know Other NA
Party ID reported 4104 306 126 0
No Party ID 1632 1350 132 0
Other 72 12 48 0
NA 0 0 0 0
Total 5808 1668 306 0
$Slovenia
der_pid Vote reported Don't know Other NA
Party ID reported 3798 348 132 0
No Party ID 1224 942 210 0
Other 54 6 60 0
NA 0 0 0 36
Total 5076 1296 402 36
$Spain
der_pid Vote reported Don't know Other NA
Party ID reported 5688 186 54 6
No Party ID 1386 786 96 6
Other 78 24 54 0
NA 0 0 0 12
Total 7152 996 204 24
$Sweden
der_pid Vote reported Don't know Other NA
Party ID reported 5274 270 78 0
No Party ID 966 696 96 0
Other 48 6 78 0
NA 0 0 0 12
Total 6288 972 252 12
$`United Kingdom`
der_pid Vote reported Don't know Other NA
Party ID reported 4548 264 36 18
No Party ID 1872 798 84 0
Other 12 0 24 0
NA 0 0 0 18
Total 6432 1062 144 36
Overview of data distribution
Respondents -> Party ID -> Vote report
In words, respondents either report a partisan identity (i.e., a felt attachement to a political party) or they deny the presence of such feelings.
# A tibble: 3 × 2
pid_equal_vote_id n
<dbl> <int>
1 0 3626
2 1 12437
3 NA 2294
In [20]:
Code
eu25games2019 <- eu25games2019 |>mutate(pid_equal_vote_id =case_when( der_pid =="Party ID reported"& der_vote_cat =="Vote reported"& der_vote_combined_id == ext_q_party_id_pf_id ~1, der_pid =="Party ID reported"& der_vote_cat =="Vote reported"& der_vote_combined_id != ext_q_party_id_pf_id ~0,.default =NA ),pid_equal_vote_name =case_when( der_pid =="Party ID reported"& der_vote_cat =="Vote reported"& der_vote_combined_name == ext_q_party_id_pf_name ~1, der_pid =="Party ID reported"& der_vote_cat =="Vote reported"& der_vote_combined_name != ext_q_party_id_pf_name ~0,.default =NA ) )# manually recode some instances where the casewhen check above yielded different but inspection revealed its basically the same partyeu25games2019 <- eu25games2019 |>mutate(# New column using case_when for manual line-by-line recodingpid_equal_vote_name2 =case_when(# Case 1: Party names are already identical (from pid_equal_vote_name = 1) pid_equal_vote_name ==1~1,# Case 2: Polish Koalicja Obywatelska (PO, SLD, Spring, PSL, Nowoczesna) pid_equal_vote_name ==0& ext_q_party_id_pf_name %in%c("Platforma Obywatelska","Sojusz Lewicy Demokratycznej","Spring","Polskie Stronnictwo Ludowe","Nowoczesna" ) & der_vote_combined_name =="Koalicja Obywatelska"~1,# Case 3: Spanish Unidas Podemos (Podemos, Izquierda Unida) pid_equal_vote_name ==0& ext_q_party_id_pf_name %in%c("Podemos","Izquierda Unida" ) & der_vote_combined_name =="Unidas Podemos"~1,# Case 4: Dutch ChristenUnie — SGP pid_equal_vote_name ==0& ext_q_party_id_pf_name %in%c("ChristenUnie","Staatkundig Gereformeerde Partij" ) & der_vote_combined_name =="ChristenUnie — Staatkundig Gereformeerde Partij"~1,# Case 5: Hungarian Fidesz — KDNP (using grepl for robustness against long name) pid_equal_vote_name ==0& ext_q_party_id_pf_name %in%c("Fidesz — Magyar Polgári Szövetség","Kereszténydemokrata Néppárt" ) &grepl("Fidesz — KDNP pártszövetség", der_vote_combined_name,fixed =TRUE ) ~1,# Case 6: Polish Konfederacja Wolność i Niepodległość (KNP, KORWiN, Kukiz'15) pid_equal_vote_name ==0& ext_q_party_id_pf_name %in%c("Kongres Nowej Prawicy","Koalicja Odnowy Rzeczypospolitej Wolność i Nadzieja KORWiN","Kukiz'15" ) & der_vote_combined_name =="Konfederacja Wolność i Niepodległość"~1,# Case 7: Latvian Attīstībai/Par! pid_equal_vote_name ==0& ext_q_party_id_pf_name =="Kustība Par!"& der_vote_combined_name =="Attīstībai/Par!"~1,# Case 8: French LREM/Renaissance pid_equal_vote_name ==0& ext_q_party_id_pf_name =="Mouvement démocrate"& der_vote_combined_name =="La République En Marche! / Renaissance"~1,# Case 9: Catalan JxCat (Partit Demòcrata Europeu Català) pid_equal_vote_name ==0& ext_q_party_id_pf_name =="Partit Demòcrata Europeu Català"& der_vote_combined_name =="Junts per Catalunya — Partit Demòcrata Europeu Català"~1,# Default: All other cases (where pid_equal_vote_name was 0 and no manual case matched)TRUE~ pid_equal_vote_name ) )eu25games2019 |>distinct(meta_pid, .keep_all = T) |>count(pid_equal_vote_name2)
# A tibble: 3 × 2
pid_equal_vote_name2 n
<dbl> <int>
1 0 3697
2 1 13220
3 NA 12910
Schematic overview
In [21]:
Code
flowchart TD A(Respondents <br> N = 29,827) --> B(No Party ID <br> N = 10,880) A(Respondents <br> N = 29,827) --> C(Party ID <br> N = 18,357) B --> D(No Vote <br> N = 3,900) B --> E(Vote <br> N = 6,234) C --> F(No Vote <br> N = 1,030) C --> G(Vote <br> N = 16,917) G --> H(Same as PID <br> N = 13,220) G --> I(Diff from PID <br> N = 3,697)
flowchart TD
A(Respondents <br> N = 29,827) --> B(No Party ID <br> N = 10,880)
A(Respondents <br> N = 29,827) --> C(Party ID <br> N = 18,357)
B --> D(No Vote <br> N = 3,900)
B --> E(Vote <br> N = 6,234)
C --> F(No Vote <br> N = 1,030)
C --> G(Vote <br> N = 16,917)
G --> H(Same as PID <br> N = 13,220)
G --> I(Diff from PID <br> N = 3,697)
# A tibble: 179 × 4
meta_country der_nopid der_vote_cat n
<chr> <dbl> <fct> <int>
1 Austria 0 Vote reported 3822
2 Austria 0 Don't know 198
3 Austria 0 Other 30
4 Austria 0 NA 6
5 Austria 1 Vote reported 2622
6 Austria 1 Don't know 900
7 Austria 1 Other 78
8 Austria 1 NA 6
9 Belgium 0 Vote reported 5064
10 Belgium 0 Don't know 222
# ℹ 169 more rows
Code
total_counts <- df_reshaped |>group_by(meta_country, der_nopid) |>summarise(n =sum(n), .groups ="drop") |>mutate(nopid2 =if_else(der_nopid ==1, "No PID", "PID"),toprint =paste0( nopid2,"\n",as.character(n) ),toprint2 =as.character(n) )ggplot(df_reshaped, aes(x =as.factor(der_nopid), y = n, fill = der_vote_cat)) +geom_col() +geom_text(data = total_counts,aes(label = toprint2, fill ="black"),vjust =if_else( total_counts$der_nopid ==1,0,1 ),size =3 ) +facet_wrap(~meta_country) +labs(y ="N", x ="") +scale_x_discrete(labels =c("0"="PID", "1"="No PID")) +scale_fill_manual(values =c("Don't know"="darkgray","NA"="black","Other"="orange","Vote reported"="gold" ) ) +theme_pubr()
Warning in geom_text(data = total_counts, aes(label = toprint2, fill =
"black"), : Ignoring unknown aesthetics: fill
Distribution of Reported Partisan Affiliation and Vote Choice/Intention across included European countries.
Distribution of partisan types, by country. Stacked horizontal bars show the within-country share (%) of three partisan types: explicit partisans (respondents who reported a subjective attachement to a party, \(T_i=1\)), implicit partisans (respondents who reported no attachement but did report a vote preference or intention, \(T_i=0\)), and respondents who reported neither (none, \(T_i = \emptyset\)). Percentages sum to 100% within each country, with country samples containing about \(1,100\) respondents each (detailed numbers are reported in appendix section X).
Exploratory analysis of country specific ingroup and outgroup dynamics by partisan type
`summarise()` has grouped output by 'meta_country'. You can override using the
`.groups` argument.
Code
token_means_pooled <- eu25games2019 |>filter(meta_game =="dict") |>filter(!der_outpartisan_comb %in%c("97_eunat_expl","97_eunat_impl","98_outnat_expl","98_outnat_impl","99_outnatEU_nopid","99_outnat_nopid" ) &!is.na(der_outpartisan_comb) ) |>group_by(der_outpartisan_comb) |>summarise(m =mean(cj_token_logged),s =sd(cj_token_logged),n =n() ) |>ungroup()token_means_pooled <- token_means_pooled |>mutate(meta_country ="Pooled") |>select(meta_country, der_outpartisan_comb, m, s, n)token_means <- token_means |>bind_rows(token_means_pooled)qoi_bycountry <- token_means |>group_by(meta_country) |>summarise(# Explicit Conditions (expl_Type_Stat)# IF_expl: Difference (2 - 1)expl_IF_diff = m[der_outpartisan_comb =="2_co_expl"] - m[der_outpartisan_comb =="1_control_expl"],expl_IF_SE =sqrt( (s[der_outpartisan_comb =="2_co_expl"]^2/ n[der_outpartisan_comb =="2_co_expl"]) + (s[der_outpartisan_comb =="1_control_expl"]^2/ n[der_outpartisan_comb =="1_control_expl"]) ),expl_IF_CI_LOWER = expl_IF_diff -1.96* expl_IF_SE,expl_IF_CI_UPPER = expl_IF_diff +1.96* expl_IF_SE,# OD_expl: Difference (1 - 3)expl_OD_diff = m[der_outpartisan_comb =="1_control_expl"] - m[der_outpartisan_comb =="3_out_expl"],expl_OD_SE =sqrt( (s[der_outpartisan_comb =="1_control_expl"]^2/ n[der_outpartisan_comb =="1_control_expl"]) + (s[der_outpartisan_comb =="3_out_expl"]^2/ n[der_outpartisan_comb =="3_out_expl"]) ),expl_OD_CI_LOWER = expl_OD_diff -1.96* expl_OD_SE,expl_OD_CI_UPPER = expl_OD_diff +1.96* expl_OD_SE,# AP_expl: Difference (2 - 3)expl_AP_diff = m[der_outpartisan_comb =="2_co_expl"] - m[der_outpartisan_comb =="3_out_expl"],expl_AP_SE =sqrt( (s[der_outpartisan_comb =="2_co_expl"]^2/ n[der_outpartisan_comb =="2_co_expl"]) + (s[der_outpartisan_comb =="3_out_expl"]^2/ n[der_outpartisan_comb =="3_out_expl"]) ),expl_AP_CI_LOWER = expl_AP_diff -1.96* expl_AP_SE,expl_AP_CI_UPPER = expl_AP_diff +1.96* expl_AP_SE,# Implicit Conditions (impl_Type_Stat)# IF_impl: Difference (5 - 4)impl_IF_diff = m[der_outpartisan_comb =="5_co_impl"] - m[der_outpartisan_comb =="4_control_impl"],impl_IF_SE =sqrt( (s[der_outpartisan_comb =="5_co_impl"]^2/ n[der_outpartisan_comb =="5_co_impl"]) + (s[der_outpartisan_comb =="4_control_impl"]^2/ n[der_outpartisan_comb =="4_control_impl"]) ),impl_IF_CI_LOWER = impl_IF_diff -1.96* impl_IF_SE,impl_IF_CI_UPPER = impl_IF_diff +1.96* impl_IF_SE,# OD_impl: Difference (4 - 6)impl_OD_diff = m[der_outpartisan_comb =="4_control_impl"] - m[der_outpartisan_comb =="6_out_impl"],impl_OD_SE =sqrt( (s[der_outpartisan_comb =="4_control_impl"]^2/ n[der_outpartisan_comb =="4_control_impl"]) + (s[der_outpartisan_comb =="6_out_impl"]^2/ n[der_outpartisan_comb =="6_out_impl"]) ),impl_OD_CI_LOWER = impl_OD_diff -1.96* impl_OD_SE,impl_OD_CI_UPPER = impl_OD_diff +1.96* impl_OD_SE,# AP_impl: Difference (5 - 6)impl_AP_diff = m[der_outpartisan_comb =="5_co_impl"] - m[der_outpartisan_comb =="6_out_impl"],impl_AP_SE =sqrt( (s[der_outpartisan_comb =="5_co_impl"]^2/ n[der_outpartisan_comb =="5_co_impl"]) + (s[der_outpartisan_comb =="6_out_impl"]^2/ n[der_outpartisan_comb =="6_out_impl"]) ),impl_AP_CI_LOWER = impl_AP_diff -1.96* impl_AP_SE,impl_AP_CI_UPPER = impl_AP_diff +1.96* impl_AP_SE,# None Condition (none_Type_Stat)# OD_none: Difference (7 - 8)none_OD_diff = m[der_outpartisan_comb =="7_control_nopid"] - m[der_outpartisan_comb =="8_ptycue_nopid"],none_OD_SE =sqrt( (s[der_outpartisan_comb =="7_control_nopid"]^2/ n[der_outpartisan_comb =="7_control_nopid"]) + (s[der_outpartisan_comb =="8_ptycue_nopid"]^2/ n[der_outpartisan_comb =="8_ptycue_nopid"]) ),none_OD_CI_LOWER = none_OD_diff -1.96* none_OD_SE,none_OD_CI_UPPER = none_OD_diff +1.96* none_OD_SE )tidy_qoi <- qoi_bycountry |># 1. Pivot the data from wide to long formatpivot_longer(# Select all columns except the grouping variablecols =-meta_country,# 2. Split the column names into three parts: Condition, Type, and Valuenames_to =c("pid_type_raw", "diff_type", ".value"),# 3. Define the pattern for separation (Condition_Type_Statistic)names_pattern ="(expl|impl|none)_([A-Z]+)_(diff|SE|CI_LOWER|CI_UPPER)$"# Explanation:# (expl|impl|none) -> Captures the Condition into 'pid_type_raw'# ([A-Z]+) -> Captures the Type (IF, OD, AP) into 'diff_type'# (diff|SE|CI_LOWER|CI_UPPER) -> Captures the Statistic into '.value' (creating columns diff, SE, CI_LOWER, CI_UPPER) ) |># 4. Clean up the pid_type and rename the 'diff' columnmutate(pid_type =case_match( pid_type_raw,"expl"~"explicit","impl"~"implicit","none"~"none" ) ) |>rename(Difference = diff ) |># 5. Select and reorder final columns for readabilityselect( meta_country, pid_type, diff_type, Difference, SE,starts_with("CI_") )plot_data <- tidy_qoi |>mutate(country_condition =paste(meta_country, pid_type, sep =" | "),country_condition =fct_inorder(country_condition) ) |>mutate(# extract pooled levelscountry_condition =fct_relevel( country_condition,grep("^Pooled \\|", levels(country_condition), value =TRUE),after =Inf# use 0 for top, Inf for bottom ),country_condition =fct_rev(country_condition),diff_type =factor(diff_type, levels =c("IF", "OD", "AP")) )# 2. Create the Plotggplot( plot_data,aes(y = country_condition,x = Difference,shape = pid_type,color = meta_country )) +# Add the vertical line at zero (to check for significance)geom_vline(xintercept =0, linetype ="dashed", color ="red", alpha =0.6) +# Add the Confidence Intervals (horizontal error bars)geom_errorbarh(aes(xmin = CI_LOWER, xmax = CI_UPPER),height =0.2,linewidth =0.5 ) +# Add the point estimategeom_point(size =2.5) +# Crucial Step: Facet the plot horizontally by the Difference Type (IF, OD, AP)facet_wrap(~diff_type,ncol =3,scales ="free_x"# Allow x-axis to scale independently for each difference type ) +# Labels and theminglabs(y ="Country | PID Type",x ="Mean Difference (Point Estimate with 95% CI)" ) +theme_pubr() +scale_color_manual(values =c(rep(c("#648FFF","#DC267F","#785EF0","#FE6100","#FFB000" ),5 ),"black" ) ) +theme(# Reduce font size for Y-axis labels if they are too longaxis.text.y =element_text(size =8, hjust =0),# Ensure facet titles are clearstrip.text =element_text(face ="bold"),legend.position ="none" )
Warning: `geom_errorbarh()` was deprecated in ggplot2 4.0.0.
ℹ Please use the `orientation` argument of `geom_errorbar()` instead.
`height` was translated to `width`.
Exploratory token allocation behavior by country and pid type in the dictator game: ingroup favoritism, outgroup derogation and affective polarization. The figure shows mean differences in token allocation with 95% confidence intervals. IF = mean(token2co) - mean(token2control), OD = mean(token2control) - mean(token2out), AP = mean(token2co) - mean(token2out)
`summarise()` has grouped output by 'meta_country'. You can override using the
`.groups` argument.
Code
qoi_bycountry <- token_means |>group_by(meta_country) |>summarise(# Explicit Conditions (expl_Type_Stat)# IF_expl: Difference (2 - 1)expl_IF_diff = m[der_outpartisan_comb =="2_co_expl"] - m[der_outpartisan_comb =="1_control_expl"],expl_IF_SE =sqrt( (s[der_outpartisan_comb =="2_co_expl"]^2/ n[der_outpartisan_comb =="2_co_expl"]) + (s[der_outpartisan_comb =="1_control_expl"]^2/ n[der_outpartisan_comb =="1_control_expl"]) ),expl_IF_CI_LOWER = expl_IF_diff -1.96* expl_IF_SE,expl_IF_CI_UPPER = expl_IF_diff +1.96* expl_IF_SE,# OD_expl: Difference (1 - 3)expl_OD_diff = m[der_outpartisan_comb =="1_control_expl"] - m[der_outpartisan_comb =="3_out_expl"],expl_OD_SE =sqrt( (s[der_outpartisan_comb =="1_control_expl"]^2/ n[der_outpartisan_comb =="1_control_expl"]) + (s[der_outpartisan_comb =="3_out_expl"]^2/ n[der_outpartisan_comb =="3_out_expl"]) ),expl_OD_CI_LOWER = expl_OD_diff -1.96* expl_OD_SE,expl_OD_CI_UPPER = expl_OD_diff +1.96* expl_OD_SE,# AP_expl: Difference (2 - 3)expl_AP_diff = m[der_outpartisan_comb =="2_co_expl"] - m[der_outpartisan_comb =="3_out_expl"],expl_AP_SE =sqrt( (s[der_outpartisan_comb =="2_co_expl"]^2/ n[der_outpartisan_comb =="2_co_expl"]) + (s[der_outpartisan_comb =="3_out_expl"]^2/ n[der_outpartisan_comb =="3_out_expl"]) ),expl_AP_CI_LOWER = expl_AP_diff -1.96* expl_AP_SE,expl_AP_CI_UPPER = expl_AP_diff +1.96* expl_AP_SE,# Implicit Conditions (impl_Type_Stat)# IF_impl: Difference (5 - 4)impl_IF_diff = m[der_outpartisan_comb =="5_co_impl"] - m[der_outpartisan_comb =="4_control_impl"],impl_IF_SE =sqrt( (s[der_outpartisan_comb =="5_co_impl"]^2/ n[der_outpartisan_comb =="5_co_impl"]) + (s[der_outpartisan_comb =="4_control_impl"]^2/ n[der_outpartisan_comb =="4_control_impl"]) ),impl_IF_CI_LOWER = impl_IF_diff -1.96* impl_IF_SE,impl_IF_CI_UPPER = impl_IF_diff +1.96* impl_IF_SE,# OD_impl: Difference (4 - 6)impl_OD_diff = m[der_outpartisan_comb =="4_control_impl"] - m[der_outpartisan_comb =="6_out_impl"],impl_OD_SE =sqrt( (s[der_outpartisan_comb =="4_control_impl"]^2/ n[der_outpartisan_comb =="4_control_impl"]) + (s[der_outpartisan_comb =="6_out_impl"]^2/ n[der_outpartisan_comb =="6_out_impl"]) ),impl_OD_CI_LOWER = impl_OD_diff -1.96* impl_OD_SE,impl_OD_CI_UPPER = impl_OD_diff +1.96* impl_OD_SE,# AP_impl: Difference (5 - 6)impl_AP_diff = m[der_outpartisan_comb =="5_co_impl"] - m[der_outpartisan_comb =="6_out_impl"],impl_AP_SE =sqrt( (s[der_outpartisan_comb =="5_co_impl"]^2/ n[der_outpartisan_comb =="5_co_impl"]) + (s[der_outpartisan_comb =="6_out_impl"]^2/ n[der_outpartisan_comb =="6_out_impl"]) ),impl_AP_CI_LOWER = impl_AP_diff -1.96* impl_AP_SE,impl_AP_CI_UPPER = impl_AP_diff +1.96* impl_AP_SE,# None Condition (none_Type_Stat)# OD_none: Difference (7 - 8)none_OD_diff = m[der_outpartisan_comb =="7_control_nopid"] - m[der_outpartisan_comb =="8_ptycue_nopid"],none_OD_SE =sqrt( (s[der_outpartisan_comb =="7_control_nopid"]^2/ n[der_outpartisan_comb =="7_control_nopid"]) + (s[der_outpartisan_comb =="8_ptycue_nopid"]^2/ n[der_outpartisan_comb =="8_ptycue_nopid"]) ),none_OD_CI_LOWER = none_OD_diff -1.96* none_OD_SE,none_OD_CI_UPPER = none_OD_diff +1.96* none_OD_SE )tidy_qoi <- qoi_bycountry |># 1. Pivot the data from wide to long formatpivot_longer(# Select all columns except the grouping variablecols =-meta_country,# 2. Split the column names into three parts: Condition, Type, and Valuenames_to =c("pid_type_raw", "diff_type", ".value"),# 3. Define the pattern for separation (Condition_Type_Statistic)names_pattern ="(expl|impl|none)_([A-Z]+)_(diff|SE|CI_LOWER|CI_UPPER)$"# Explanation:# (expl|impl|none) -> Captures the Condition into 'pid_type_raw'# ([A-Z]+) -> Captures the Type (IF, OD, AP) into 'diff_type'# (diff|SE|CI_LOWER|CI_UPPER) -> Captures the Statistic into '.value' (creating columns diff, SE, CI_LOWER, CI_UPPER) ) |># 4. Clean up the pid_type and rename the 'diff' columnmutate(pid_type =case_match( pid_type_raw,"expl"~"explicit","impl"~"implicit","none"~"none" ) ) |>rename(Difference = diff ) |># 5. Select and reorder final columns for readabilityselect( meta_country, pid_type, diff_type, Difference, SE,starts_with("CI_") )# 1. Prepare the data for plottingplot_data <- tidy_qoi |># Create a single factor combining country and condition for the Y-axismutate(# Combine country and pid_type into one label (e.g., "Austria | explicit")country_condition =factor(paste(meta_country, pid_type, sep =" | ")),# Use fct_inorder to maintain the logical order (country-by-country)# Then fct_rev reverses the entire factor so the first country appears at the top of the Y-axiscountry_condition =fct_rev(fct_inorder(country_condition)) ) |># Optional: Clean up diff_type for better facet labelsmutate(diff_type =factor(diff_type, levels =c("IF", "OD", "AP")) )# 2. Create the Plotggplot( plot_data,aes(y = country_condition,x = Difference,shape = pid_type,color = meta_country )) +# Add the vertical line at zero (to check for significance)geom_vline(xintercept =0, linetype ="dashed", color ="red", alpha =0.6) +# Add the Confidence Intervals (horizontal error bars)geom_errorbarh(aes(xmin = CI_LOWER, xmax = CI_UPPER),height =0.2,linewidth =0.5 ) +# Add the point estimategeom_point(size =2.5) +# Crucial Step: Facet the plot horizontally by the Difference Type (IF, OD, AP)facet_wrap(~diff_type,ncol =3,scales ="free_x"# Allow x-axis to scale independently for each difference type ) +# Labels and theminglabs(y ="Country | PID Type",x ="Mean Difference (Point Estimate with 95% CI)" ) +theme_pubr() +scale_color_manual(values =rep(c("#648FFF","#DC267F","#785EF0","#FE6100","#FFB000" ),5 ) ) +theme(# Reduce font size for Y-axis labels if they are too longaxis.text.y =element_text(size =8, hjust =0),# Ensure facet titles are clearstrip.text =element_text(face ="bold"),legend.position ="none" )
`height` was translated to `width`.
Exploratory token allocation behavior by country and pid type in the trust game: ingroup favoritism, outgroup derogation and affective polarization. The figure shows mean differences in token allocation with 95% confidence intervals. IF = mean(token2co) - mean(token2control), OD = mean(token2control) - mean(token2out), AP = mean(token2co) - mean(token2out)
der_partisan_anchor n percent valid_percent
Die Grünen — Die grüne Alternative 834 0.1 0.1
EU-Austrittspartei (EUAUS)[og] 42 0.0 0.0
EUROPA Jetzt – Initiative Johannes Voggenhuber[og] 60 0.0 0.0
Freiheitliche Partei Österreichs 1470 0.2 0.2
KPÖ Plus – European Left, offene Liste[og] 60 0.0 0.0
Kommunistische Partei Österreichs 84 0.0 0.0
Liste Peter Pilz 78 0.0 0.0
NEOS — Das Neue Österreich 696 0.1 0.1
Piraten[og] 30 0.0 0.0
Sozialdemokratische Partei Österreichs 1620 0.2 0.2
Österreichische Volkspartei 1626 0.2 0.2
<NA> 1062 0.1 NA
Total 7662 1.0 1.0
Sample composition by country and age group. Numbers denote respondents.
Country
18 to 25
26 to 35
36 to 45
46 to 55
56 to 65
66 to 75
> 75
Austria
144
177
249
263
286
142
0
Belgium
197
132
160
235
333
239
3
Bulgaria
57
195
231
250
212
33
0
Croatia
119
251
272
331
205
47
0
Czech Republic
88
187
227
219
281
126
0
Denmark
132
134
139
208
321
249
4
Estonia
56
168
164
283
265
7
0
Finland
125
178
210
242
259
137
1
France
123
176
242
267
279
51
0
Germany
125
184
200
240
313
117
0
Greece
77
202
376
318
136
34
0
Hungary
51
175
196
166
273
117
1
Ireland
128
216
223
187
169
120
0
Italy
104
196
264
195
294
98
2
Latvia
78
251
231
338
239
6
0
Lithuania
223
311
257
250
212
2
0
Netherlands
149
126
161
234
340
194
3
Poland
200
342
222
187
196
42
0
Portugal
112
260
289
231
218
67
1
Romania
128
339
373
347
202
65
0
Slovakia
139
223
282
290
250
108
1
Slovenia
97
186
246
284
234
72
0
Spain
125
293
355
305
228
66
1
Sweden
124
165
156
234
297
261
3
United Kingdom
121
184
196
234
268
250
1
Total
3022
5251
5921
6338
6310
2650
21
Model DAG
In [41]:
Code
dag <-dagitty("dag {\"Z1\" [pos=\"0, 1\"]A [pos=\"0, 2\"]C [pos=\"2, 1\"]R [pos=\"1 ,1\"]T [exposure,pos=\"1 , 2\"]Y [outcome,pos=\"1 ,0\"]Z [pos=\"0 ,0\"]\"Z1\" -> RA -> RA -> TC -> TC -> YR -> YT -> RZ -> Y}")tidy_dag <-tidy_dagitty(dag)label_mapping <-tibble(name =c("A", "C", "R", "T", "Y", "Z", "Z1"),new_label =c("italic(A[i])", # partisan anchor of respondent i"italic(C[i])", # respondent confounders"italic(R[ri])", # relationship (round r, respondent i)"italic(T[i])", # partisan type of respondent i"italic(Y[riac])", # tokens (r,i,a,c)"italic(Z[r]^{other})", # other randomized cues (round r)"italic(Z[r]^{party})"# party cue shown in round r ))tidy_dag <- tidy_dag |>left_join( label_mapping,by =join_by(name) )ggdag(tidy_dag) +geom_dag_node() +geom_dag_text(aes(label = new_label), parse = T) +geom_dag_edges() +theme_dag() +theme(aspect.ratio =1/1.618034 )
Directed acyclic graph of the causal data-generating process. Respondents have a partisan anchor \(A_i\), representing the party they feel attached to (explicit partisans) or intend to vote for (implicit partisans). Partisan type \(T_i\) (explicit vs. implicit) is only defined for respondents with a partisan anchor and is therefore a child node of \(A_i\). Each conjoint profile shown in round \(r\) presents randomized attributes: a partisan cue \(Z^{party}_r\) and other attributes \(Z^{other}_r\). The partisan-relationship variable \(R_{ri} = f(A_i, Z^{party}_r)\) determines whether the profile is interpreted as a co-partisan, out-partisan, or neutral for respondent \(i\). Token allocations \(Y_{riac}\) are affected by both \(R_{ri}\) and \(Z^{other}_r\), with the effect of \(R_{ri}\) theorized to depend on \(T_i\). Because \(T_i\) is observational, \(C_i\) denotes potential confounders of both \(T_i\) and \(Y_{ri}\), highlighting the assumptions required for causal interpretation.
Model data
In [42]:
Code
df_modelvars <- eu25games2019 |>filter( der_conational =="co-national",!is.na(der_partisan_type) ) |>select(# outcome Y cj_token,# vars of interest der_partisan_type, # T der_partisan_relationship, # R# identifiers/hierarchical groupings meta_pid, der_partisan_anchor, meta_country,# game variables meta_game, meta_game_lab,# conjoint controls Z meta_round, meta_wave, cj_age_en, cj_reli_en, cj_class_en, cj_sex_en, cj_eupos_shown,# =========================================================================# COVARIATES (C) FOR CAUSAL ISOLATION# =========================================================================# --- BLOCK 1: Fundamental Political Identity and Ideology (Core Drivers of T & Y) --- q_lrpos2, # Left-Right ideological self-placement (Controls for core political position) q_eupos2, # EU integration position (Controls for major second dimension position) q_econ_nativism, # Attitudes towards economic nativism (Controls for key sociotropic threat perception) q_cult_nativism, # Attitudes towards cultural nativism (Controls for key sociotropic identity boundary) q_religion_en, # Respondent's religious affiliation (Controls for a major social cleavage/identity)# --- BLOCK 2: Anti-System & Populist Attitudes (CRUCIAL CONFOUNDERS for T) ---# These variables control for system-level dissatisfaction/cynicism that pushes# individuals to reject EXPLICIT partisan identity (T=0) while also driving Y. q_satis_demo_country, # Satisfaction with democracy in the country (System trust) q_understand_nat_pol, # Political efficacy (national level) q_nat_politicians_care, # Political responsiveness (national level) q_nat_public_say, # Political efficacy (national level) q_understand_eu_pol, # Political efficacy (EU level) q_eu_politicians_care, # Political responsiveness (EU level) q_eu_public_say, # Political efficacy (EU level) q_parties_harm, # Anti-party sentiment ("Parties do more harm than good") q_officials_talk_action, # Anti-elitism ("Officials talk too much") q_prefer_citizen_rep, # People-centrism ("Prefer citizens to politicians") q_people_make_decisions, # People-centrism ("People, not politicians, should decide") q_politicians_follow_people, # People-centrism ("Politicians must follow the people's will") q_politics_good_evil, # Manichaean worldview ("Politics is good vs. evil") q_people_unaware, # System cynicism ("People are unaware") q_leaders_educated, # Anti-populism (Elitism) q_expert_decisions, # Anti-populism (Expert governance) q_listen_other_groups, # Tolerance/Pluralism q_democracy_compromise, # Tolerance/Pluralism# --- BLOCK 3: Political Engagement & General Identity (Predictors of T and Y) --- q_attach_country, # Emotional attachment to one's country q_attach_eu, # Emotional attachment to the EU q_attach_eur, # Emotional attachment to Europe q_interest_pol_country, # Political engagement (national) q_interest_pol_eu, # Political engagement (EU) q_election_importance, # Political engagement (election importance)# --- BLOCK 4: Socioeconomic Status (SES) and Economic Context (Background Predictors) --- q_edu, # Education level q_perc_class, # Subjective social class q_eval_finance_household, # Micro-level economic evaluation q_eval_job, # Job/Employment evaluation q_eval_econ_country, # Macro-level economic evaluation (country) q_eval_econ_eur, # Macro-level economic evaluation (Europe)# --- BLOCK 5: Demographics and Fixed Traits (General Controls) --- q_gender, # Respondent's gender q_age, # Respondent's age q_rural_urban, # Residence setting q_risk_taking, # General propensity for risk-taking behavior q_future_discount # Patience/future discounting trait )na_counts_modelvars1 <- df_modelvars |># 1. Summarise: Calculate the sum of NAs for every column.summarise(across(.cols =everything(),.fns =~sum(is.na(.)),.names ="na_count_{.col}"# Temporarily rename columns for pivot )) |># 2. Pivot: Convert the wide one-row summary into a tall, two-column table.pivot_longer(cols =everything(),names_to ="Variable",values_to ="NA_Count" ) |># 3. Clean: Remove the temporary prefix for cleaner variable names.mutate(Variable =str_remove(Variable, "na_count_")) |># 4. Arrange: Sort the result to see the variables with the most NAs first.arrange(desc(NA_Count))# Remove variables with too many NAs (>10k)df_modelvars <- df_modelvars |>select(-q_nat_politicians_care,-q_nat_public_say,-q_eu_politicians_care,-q_eu_public_say,-q_prefer_citizen_rep,-q_people_make_decisions,-q_politicians_follow_people,-q_attach_country,-q_attach_eu,-q_attach_eur,-q_election_importance )# Recode dont know answers correctlydf_modelvars <- df_modelvars |>mutate(q_satis_demo_country =case_when( q_satis_demo_country ==5| q_satis_demo_country ==6~NA,.default = q_satis_demo_country ),q_perc_class =if_else( q_perc_class ==6,NA, q_perc_class ),q_eval_finance_household =if_else( q_eval_finance_household ==6,NA, q_eval_finance_household ),q_eval_job =if_else( q_eval_job ==6,NA, q_eval_job ),q_eval_econ_country =if_else( q_eval_econ_country ==6,NA, q_eval_econ_country ),q_eval_econ_eur =if_else( q_eval_econ_eur ==6,NA, q_eval_econ_eur ),q_rural_urban =if_else( q_rural_urban ==4,NA, q_rural_urban ) )# Categeorical to factorsdf_modelvars <- df_modelvars |>mutate(# categorical to factorsq_perc_class =factor( q_perc_class,levels =c(1, 2, 3, 4, 5),labels =c("Working class","Lower middle class","Middle class","Upper middle class","Upper class" ) ),q_rural_urban =factor( q_rural_urban,levels =c(1, 2, 3),labels =c("Rural area or village","Small or middle sized town","Large town" ) ),q_gender =factor( q_gender,levels =c(1, 2, 3),labels =c("Male", "Female", "Other") ),q_religion_en =as_factor(q_religion_en) )# standardize survey scalesdf_modelvars <- df_modelvars |>mutate(across(.cols =c( q_lrpos2, q_eupos2, q_econ_nativism, q_cult_nativism, q_satis_demo_country, q_understand_nat_pol, q_understand_eu_pol, q_parties_harm, q_officials_talk_action, q_politics_good_evil, q_people_unaware, q_leaders_educated, q_expert_decisions, q_listen_other_groups, q_democracy_compromise, q_interest_pol_country, q_interest_pol_eu, q_eval_finance_household, q_eval_job, q_eval_econ_country, q_eval_econ_eur, q_risk_taking, q_future_discount, q_edu, q_age ), # List all continuous variables to standardize.fns =~scale(.)[, 1], # Apply the scale() function.names ="{.col}_z"# Name the new standardized columns with a '_z' suffix ) )# Check again how missings have changedna_counts_modelvars2 <- df_modelvars |># 1. Summarise: Calculate the sum of NAs for every column.summarise(across(.cols =everything(),.fns =~sum(is.na(.)),.names ="na_count_{.col}"# Temporarily rename columns for pivot )) |># 2. Pivot: Convert the wide one-row summary into a tall, two-column table.pivot_longer(cols =everything(),names_to ="Variable",values_to ="NA_Count" ) |># 3. Clean: Remove the temporary prefix for cleaner variable names.mutate(Variable =str_remove(Variable, "na_count_")) |># 4. Arrange: Sort the result to see the variables with the most NAs first.arrange(desc(NA_Count))# Global variable mapping and final df for modellingdf_modelvars <- df_modelvars |>select(starts_with("cj_"),starts_with("der_"),starts_with("meta_"),ends_with("_z"), q_religion_en, q_perc_class, q_rural_urban, q_gender )modelvars_labels <-c("Token"="cj_token","Conj. Age"="cj_age_en","Conj. Religion"="cj_reli_en","Conj. Class"="cj_class_en","Conj. Gender"="cj_sex_en","Conj. EU"="cj_eupos_shown","Type"="der_partisan_type","Relationship"="der_partisan_relationship","Anchor"="der_partisan_anchor","Resp. ID"="meta_pid","Country"="meta_country","Game"="meta_game_lab","Round"="meta_round","Wave"="meta_wave","LR Pos"="q_lrpos2_z","EU Pos"="q_eupos2_z","Econ. Nativism"="q_econ_nativism_z","Cult. Nativism"="q_cult_nativism_z","Satis. Democ."="q_satis_demo_country_z","Understand Nat. Pol."="q_understand_nat_pol_z","Understand EU Pol."="q_understand_eu_pol_z","Parties Harm"="q_parties_harm_z","Officials Talk/Action"="q_officials_talk_action_z","Politics Good/Evil"="q_politics_good_evil_z","People Unaware"="q_people_unaware_z","Leaders Educated"="q_leaders_educated_z","Expert Decisions"="q_expert_decisions_z","Listen Other Groups"="q_listen_other_groups_z","Democ. Compromise"="q_democracy_compromise_z","Interest Nat. Pol."="q_interest_pol_country_z","Interest EU Pol."="q_interest_pol_eu_z","Eval. HH Finance"="q_eval_finance_household_z","Eval. Job"="q_eval_job_z","Eval. Nat. Econ."="q_eval_econ_country_z","Eval. Eur. Econ."="q_eval_econ_eur_z","Risk Taking"="q_risk_taking_z","Future Discount"="q_future_discount_z","Education (Z)"="q_edu_z","Age (Z)"="q_age_z","Religion"="q_religion_en","Perc. Class"="q_perc_class","Rural/Urban"="q_rural_urban","Gender"="q_gender")